package com.itc.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itc.common.core.domain.R;
import com.itc.common.core.utils.LocalDateTimeUtils;
import com.itc.common.core.utils.StringUtils;
import com.itc.common.security.utils.SecurityUtils;
import com.itc.system.api.domain.SysDept;
import com.itc.system.api.domain.SysUser;
import com.itc.system.api.model.LoginUser;
import com.itc.system.domain.dto.SwitchSeatDto;
import com.itc.system.mapper.SysUserMapper;
import com.itc.system.service.SysDeptMenuService;
import com.itc.system.service.SysDeptService;
import com.itc.system.service.SysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhangyh
 * @description 针对表【sys_user(用户信息表)】的数据库操作Service实现
 * @createDate 2024-05-08 14:26:33
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
        implements SysUserService{

    @Autowired
    @Lazy
    private SysDeptService sysDeptService;

    @Autowired
    private SysDeptMenuService sysDeptMenuService;

    @Override
    public R switchSeat(SwitchSeatDto dto){
        SysUser sysUser = this.baseMapper.selectById(dto.getUserId());
        if(sysUser == null){
            return R.fail("用户信息异常");
        }
        //校验部门信息
        SysDept sysDept = sysDeptService.getById(dto.getSeatId());
        if(sysDept == null){
            return R.fail("所属部门信息异常");
        }
        sysUser.setDeptChildId(dto.getSeatId());
        sysUser.setUpdateBy(SecurityUtils.getUsername());
        sysUser.setUpdateTime(LocalDate.now().toString());
        this.baseMapper.updateById(sysUser);
        return R.ok();
    }

    @Override
    public R addUser(SysUser sysUser) {
        //查询用户名是否存在
        Long count=this.baseMapper.selectCount(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserName,sysUser.getUserName())
        );
        if (count>0){
            return R.fail("用户名已存在！！！");
        }
        //校验部门信息
        SysDept sysDept = sysDeptService.getById(sysUser.getDeptId());
        if(sysDept == null){
            return R.fail("所属部门信息异常");
        }
        if(sysDept.getDeptType().intValue() != 1){
            return R.fail("请选择部门级别信息进行绑定");
        }
        sysUser.setDeptName(sysDept.getDeptName());

        if(StringUtils.isNotBlank(sysUser.getDeptChildIds())){
            String[] deptIds = sysUser.getDeptChildIds().split(",");
            List<SysDept> deptList = sysDeptService.getBaseMapper().selectList(
                    new LambdaQueryWrapper<SysDept>()
                    .in(SysDept::getDeptId,deptIds)
                    .eq(SysDept::getDeptType,2)
            );
            if(deptIds.length != deptList.size()){
                return R.fail("席位信息不匹配或席位信息异常！");
            }
            sysUser.setSeatNames(deptList.stream().map(SysDept::getDeptName).collect(Collectors.joining(",")));
        }

        //密码加密
        sysUser.setPassword(SecurityUtils.encryptPassword(sysUser.getPassword()));
        sysUser.setUserType("00");
        sysUser.setStatus("0");
        sysUser.setDelFlag("0");
        // 获取当前的本地日期和时间
        String localDateTime = LocalDate.now().toString();
        sysUser.setLoginDate(localDateTime.toString());
        sysUser.setCreateBy(SecurityUtils.getUsername());
        sysUser.setCreateTime(localDateTime.toString());
        this.save(sysUser);
        return R.ok();
    }

    @Override
    public R updateUser(SysUser dto) {
        SysUser sysUser = this.baseMapper.selectById(dto.getUserId());
        if(sysUser == null){
            return R.fail("用户信息异常");
        }
        if(StringUtils.isNotBlank(dto.getUserName()) && !StringUtils.equals(dto.getUserName(),sysUser.getUserName())){
            //查询用户名是否存在
            Long count=this.baseMapper.selectCount(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getUserName,dto.getUserName())
            );
            if (count>0){
                return R.fail("用户名已存在！！！");
            }
        }
        BeanUtils.copyProperties(dto,sysUser);

        //校验部门信息
        SysDept sysDept = sysDeptService.getById(sysUser.getDeptId());
        if(sysDept == null){
            return R.fail("所属部门信息异常");
        }
        if(sysDept.getDeptType().intValue() != 1){
            return R.fail("用户部门信息异常");
        }
        sysUser.setDeptName(sysDept.getDeptName());

        if(StringUtils.isNotBlank(sysUser.getDeptChildIds())){
            String[] deptIds = sysUser.getDeptChildIds().split(",");
            List<SysDept> deptList = sysDeptService.getBaseMapper().selectList(
                    new LambdaQueryWrapper<SysDept>()
                            .in(SysDept::getDeptId,deptIds)
                            .eq(SysDept::getDeptType,2)
            );
            if(deptIds.length != deptList.size()){
                return R.fail("用户席位信息不匹配或席位信息异常！");
            }
            sysUser.setSeatNames(deptList.stream().map(SysDept::getDeptName).collect(Collectors.joining(",")));
        }

        sysUser.setUpdateBy(SecurityUtils.getUsername());
        sysUser.setUpdateTime(LocalDate.now().toString());
        this.baseMapper.updateById(sysUser);
        return R.ok() ;
    }

    @Override
    public R deleteUser(Long userId) {
        SysUser sysUser = this.baseMapper.selectById(userId);
        if(sysUser == null){
            return R.fail("用户信息异常");
        }
        sysUser.setDelFlag("1");
        sysUser.setUpdateTime(LocalDate.now().toString());
        sysUser.setUpdateBy(SecurityUtils.getUsername());
        this.baseMapper.updateById(sysUser);
        return R.ok() ;
    }

    @Override
    public R queryUser(Long userId) {
        SysUser sysUser = this.getById(userId);
        if(sysUser == null){
            return R.fail("用户信息异常");
        }
        return R.ok(sysUser);
    }

    @Override
    public R listByDeptId(Long deptId) {
        //当前部门及其子部门
        List<SysDept> deptList = sysDeptService.getBaseMapper().selectList(
                new LambdaQueryWrapper<SysDept>()
                        .eq(SysDept::getDelFlag,"0")
                        .and(qw -> {
                            qw.like(SysDept::getAncestors, deptId);
                            qw.or().eq(SysDept::getDeptId, deptId);
                        })
        );
        if(deptList.size() == 0){
            return R.ok(new LinkedList<>());
        }
        List<SysUser> userList = this.baseMapper.selectList(
                new LambdaQueryWrapper<SysUser>()
                        .in(SysUser::getDeptId,deptList.stream().map(SysDept::getDeptId).collect(Collectors.toList()))
        );
        return R.ok(userList);
    }

    @Override
    public R<LoginUser> getUserInfoByName(String username) {
        SysUser sysUser = this.baseMapper.selectOne(
                new LambdaQueryWrapper<SysUser>()
                        .eq(SysUser::getDelFlag,0)
                        .eq(SysUser::getUserName,username)
                        .last("limit 1")
        );
        if (StringUtils.isNull(sysUser))
        {
            return R.fail("用户名或密码错误");
        }
        LoginUser sysUserVo = new LoginUser();
        List<String> permissions = new LinkedList<>();
        if(sysUser.isAdmin()){
            permissions.add("*:*:*");
        }else{
            Long menuDeptId = sysUser.getDeptChildId() != null ? sysUser.getDeptChildId() : null;
            if(menuDeptId == null && StringUtils.isNotBlank(sysUser.getDeptChildIds())){
                menuDeptId = Long.parseLong(sysUser.getDeptChildIds().split(",")[0]);
            }
            if(menuDeptId == null && sysUser.getDeptId() != null){
                //没有绑定席位则用部门下第一个席位来进行权限返回
                List<SysDept> deptChildList = sysDeptService.list(
                        new LambdaQueryWrapper<SysDept>()
                                .eq(SysDept::getParentId,sysUser.getDeptId())
                );
                if(deptChildList.size() > 0){
                    menuDeptId = deptChildList.get(0).getDeptId();
                }
            }
            if(menuDeptId != null){
                // 权限集合
                permissions = sysDeptMenuService.getMenuPermissionByDeptId(menuDeptId);
            }
        }
        sysUserVo.setPermissions(permissions);
        sysUserVo.setUserid(sysUser.getUserId());
        sysUserVo.setUsername(sysUser.getUserName());
        sysUserVo.setSysUser(sysUser);

        //获取用户有权限的所有部门、席位信息
        sysUserVo.setDeptIds(sysDeptService.getUserDeptSeats(sysUser));

        return R.ok(sysUserVo);
    }

    @Override
    public R<JSONObject> getLoginUserInfo() {
        SysUser sysUser = this.baseMapper.selectById(SecurityUtils.getUserId());
        if(sysUser == null){
            return R.fail("用户登录信息异常");
        }
        List<String> permissions = new LinkedList<>();
        List<SysDept> deptChildList = new LinkedList<>();
        if(sysUser.isAdmin()){
            permissions.add("*:*:*");
        }else{
            if(sysUser.getDeptChildId() != null){
                //绑定了席位就以席位的权限为主
                permissions = sysDeptMenuService.getMenuPermissionByDeptId(sysUser.getDeptChildId());
            } else if(sysUser.getDeptId() != null){
                //只绑定到部门，则使用部门的权限
                permissions = sysDeptMenuService.getMenuPermissionByDeptId(sysUser.getDeptId());
            }
        }
        JSONObject ajax = new JSONObject();
        ajax.put("user", sysUser);
        ajax.put("seatInfo", deptChildList);
        ajax.put("permissions", permissions);
        return R.ok(ajax);
    }

    @Override
    public R resetPwd(Long userId) {
        SysUser sysUser = this.baseMapper.selectById(userId);
        if(sysUser == null){
            return R.fail("用户信息异常！");
        }
        sysUser.setPassword(SecurityUtils.encryptPassword("Szzdyk@123456"));
        sysUser.setUpdateBy(SecurityUtils.getUsername());
        sysUser.setUpdateTime(LocalDateTimeUtils.getCurrentLocalDateTime());
        this.baseMapper.updateById(sysUser);
        return R.ok();
    }
}




